﻿

Procedure _CreateTorusMesh_Vertex(*vertex.ModelVertex, n.l, m.l, rings.l, segments.l, rBig.f, rSmall.f)
	Protected.vec2 Dim texCoord(6), texCoordF
	Protected.vec3 posF, posS, normalF, normalS, tangentF, tangentS
	Protected.vec4 qSmall, qBig, qRot
	Quat_FromAxisComp(qSmall, 0, 0, 1, #PI*2*n/rings)
	Quat_MulV_Setup(qSmall)
	Vec3_Set(posF, rSmall, 0, 0)
	Vec3_Set(normalF, 1, 0, 0)
	Vec3_Set(tangentF, 0, 1, 0)
	Quat_MulV(posS, posF)
	Quat_MulV(normalS, normalF)
	Quat_MulV(tangentS, tangentF)
	Quat_FromAxisComp(qBig, 0, 1, 0, #PI*2*m/segments)
	Quat_MulV_Setup(qBig)
	Vec3_Set(posS, posS\x + rBig, posS\y, 0)
	Quat_MulV(@*vertex\pos, posS)
	Quat_MulV(@*vertex\normal, normalS)
	Quat_MulV(@*vertex\tangent, tangentS)
	Vec2_Set(*vertex\texcoord, n/rings, 2*m/segments)
EndProcedure
Procedure.i CreateTorusMesh(rSmall.f, rBig.f, rings.l, segments.l)
	Protected *torus.Mesh = AllocateMemory(SizeOf(Mesh))
	Protected Dim *torus\SubMeshes(1)
	Protected.ModelVertex Dim arrVertexs(100000)
	Protected.l Dim arrIndexs(100000)

	Protected.l n, m, n2, m2, i, vertexsAmount
	;{ Generation
		For n = 1 To rings
			For m = 1 To segments
				For i = 1 To 6
					Select i
						Case 1
							n2 = n-1
							m2 = m-1
						Case 2
							n2 = n
							m2 = m-1
						Case 3
							n2 = n-1
							m2 = m
						Case 4
							n2 = n
							m2 = m
						Case 5
							n2 = n
							m2 = m-1
						Case 6
							n2 = n-1
							m2 = m
					EndSelect
					_CreateTorusMesh_Vertex(@arrVertexs(vertexsAmount), n2, m2, rings, segments, rBig, rSmall)
					arrIndexs(vertexsAmount) = vertexsAmount
					vertexsAmount = vertexsAmount+1
				Next
			Next
		Next
	;}
	Protected *VAO.VAO = CreateVAO(arrVertexs(), arrIndexs(), #GL_STATIC_DRAW)
	CopyStructure(*VAO, *torus\SubMeshes(0)\VAO, VAO)
	FreeMemory(*VAO); Copy also stored in the mesh
	*torus\SubMeshes(0)\NumOfIndices = vertexsAmount
	ProcedureReturn *torus
EndProcedure

Procedure.l CreateSphereMesh(segV.l, segH.l, radius.f)
	Protected *newmesh.Mesh = AllocateMemory(SizeOf(Mesh))
	
	Dim *newmesh\SubMeshes(1)
	*newmesh\Submeshes(0)\NumOfVertices = segV * segH
	*newmesh\Submeshes(0)\NumOfIndices = segV * segH * 6
	
	;Build our sphere
	Protected.l index
	Protected.f s, t
	Protected Dim vertices.vec3(*newmesh\Submeshes(0)\NumOfVertices), Dim texcoords.vec2(*newmesh\Submeshes(0)\NumOfVertices), Dim normals.vec3(*newmesh\Submeshes(0)\NumOfVertices), Dim tangents.vec3(*newmesh\Submeshes(0)\NumOfVertices), Dim indices.l(*newmesh\Submeshes(0)\NumOfIndices)
	
	;Compute normals, texcoords, positions
	For V = 0 To segV-1
		t = V/(segV-1)
		For H = 0 To segH-1
			s = H/(segH-1)
			
			;index = V*(segH-1) + H
			texcoords(index)\x = s
			texcoords(index)\y = t
			normals(index)\x = Sin(t * 3.1415)*Cos(s * 6.283)
			normals(index)\y = Sin(t * 3.1415)*Sin(s * 6.283)
			normals(index)\z = Cos(t * 3.1415)
			vertices(index)\x = normals(index)\x * radius
			vertices(index)\y = normals(index)\y * radius
			vertices(index)\z = normals(index)\z * radius
			
			index = index + 1
		Next
	Next
	
	;Compute tangents and indices
	index = 0
	Protected.l nv, nh
	For V = 0 To segV-2
		nv = (V+1)
		For H = 0 To segH-1
			nh = (H+1) % (segH-1)
			
			indices(index  ) = V*segH + H
			indices(index+1) = V*segH + nH
			indices(index+2) = nV*segH + nH
			indices(index+3) = V*segH + H
			indices(index+4) = nV*segH + nH
			indices(index+5) = nV*segH + H
			
			index = index + 6
		Next
	Next
	
	*VAO = CreateVAO2(vertices(), normals(), tangents(), texcoords(), indices(), #GL_STATIC_DRAW)
	CopyStructure(*VAO, *newmesh\SubMeshes(0)\VAO, VAO)
	FreeMemory(*VAO); Copy also stored in the mesh
	
	ProcedureReturn *newmesh
EndProcedure
	
Procedure.l CreateCubeMesh(width.f, height.f, depth.f)
	
	Protected *newmesh.Mesh = AllocateMemory(SizeOf(Mesh))
	Dim *newmesh\SubMeshes(1)
	
	Protected Dim vertices.vec3(24), Dim texcoords.vec2(24), Dim normals.vec3(24), Dim tangents.vec3(24), Dim indices.i(24)
	
EndProcedure
; IDE Options = PureBasic 5.11 (Windows - x86)
; CursorPosition = 112
; FirstLine = 72
; Folding = -
; EnableXP